<template>
  <div class="cropper-wrapper">
    <div class="right-con">
      <Avatar v-if="!isUpload" :src="src" style="width: 150px; height: 150px;" shape="square" />
      <div v-if="isUpload" class="preview-box" :id="previewId"></div>
      <div class="button-box">
        <Upload v-if="!isUpload" action="image/upload" :before-upload="beforeUpload">
          <Button icon="md-camera" style="width: 150px;">修改头像</Button>
        </Upload>
        <div v-show="insideSrc">
          <Button style="width: 70px; margin-right: 10px;" type="warning" @click="crop">提交</Button>
          <Button style="width: 70px;" @click="cancel">取消</Button>
        </div>
      </div>
    </div>
    <div class="img-box" :style="{ opacity: isUpload ? 1 : 0 }">
      <img class="cropper-image" :id="imgId" alt="">
    </div>
  </div>
</template>
<script>
import Cropper from 'cropperjs'
import 'cropperjs/dist/cropper.min.css'
import { mapState } from 'vuex'
import { updateBasicMessage } from '@/api/user'

export default {
  name: 'Cropper',
  props: {
    src: {
      type: String,
      default: ''
    },
    preview: {
      type: Boolean,
      default: true
    },
    moveStep: {
      type: Number,
      default: 4
    }
  },
  data() {
    return {
      cropper: null,
      insideSrc: '',
      uid: '32irdwekfdiu',
      isUpload: false
    }
  },
  computed: {
    ...mapState('admin/user', [
      'info'
    ]),
    imgId() {
      return `cropper${this.uid}`
    },
    previewId() {
      return `cropper_preview${this.uid}`
    }
  },
  watch: {
    insideSrc(src) {
      this.replace(src)
    }
  },
  methods: {
    beforeUpload(file) {
      const supportTypes = ['jpg', 'jpeg', 'gif', 'png', 'webp']
      const FileExt = file.name.replace(/.+\./, '')
      if (file.size > 2048 * 1024) {
        this.$Message.warning('请上传 2M 以内的图片')
        return false
      } else if (!supportTypes.includes(FileExt.toLowerCase())) {
        this.$Message.warning(`请上传${supportTypes.join('/')}格式图片`)
        return false
      }
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = (event) => {
        this.insideSrc = event.srcElement.result
        this.isUpload = true
      }
      return false
    },
    replace(src) {
      this.cropper.replace(src)
      this.insideSrc = src
    },
    rotate() {
      this.cropper.rotate(90)
    },
    shrink() {
      this.cropper.zoom(-0.1)
    },
    magnify() {
      this.cropper.zoom(0.1)
    },
    scale(d) {
      this.cropper[`scale${d}`](-this.cropper.getData()[`scale${d}`])
    },
    move(...arg) {
      this.cropper.move(...arg)
    },
    crop() {
      this.cropper.getCroppedCanvas().toBlob(blob => {
        const reader = new FileReader()
        reader.readAsDataURL(blob)
        reader.onload = async e => {
          await this.onCropper(e.target.result.split(',')[1])
          this.isUpload = false
          this.insideSrc = ''
          this.$emit('on-crop')
        }
      })
    },
    async onCropper(base64Content) {
      const response = await updateBasicMessage({
        userId: this.info.userId,
        base64Content
      })
      this.$store.dispatch('admin/user/set', {
        ...this.info,
        headimgUrl: response.data
      }, { root: true })
      this.$Message.success('更换头像成功')
    },
    cancel() {
      this.isUpload = false
      this.insideSrc = ''
    }
  },
  mounted() {
    this.$nextTick(async () => {
      let dom = document.getElementById(this.imgId)
      this.cropper = new Cropper(dom, {
        viewMode: 1,
        aspectRatio: 1,
        preview: `#${this.previewId}`,
        checkCrossOrigin: true
      })
    })
  }
}
</script>
<style scoped lang="less">
.bg {
  background-image: url("")
}

.cropper-wrapper {
  width: 600px;
  height: 340px;

  .img-box {
    height: 340px;
    width: 430px;
    border: 1px solid #ebebeb;
    display: inline-block;
    .bg;

    img {
      max-width: 100%;
      display: block;
    }
  }

  .right-con {
    display: inline-block;
    width: 170px;
    vertical-align: top;
    box-sizing: border-box;
    padding: 0 10px;

    .preview-box {
      height: 150px !important;
      width: 100% !important;
      overflow: hidden;
      border: 1px solid #ebebeb;
      .bg;
    }

    .button-box {
      padding: 10px 0 0;
    }
  }
}
</style>